package jianli;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;

/**
 * 文件上传
 * 		思路:读前端数据及文件，写到服务器
 * 		1.form表单的enctype 必须值为:multipart/form-data
 *		2.接收文件上传的servlet,必须有 @MultipartConfig注解
		3.使用request.getPart(name值) : 获取文件对象
		4.使用part.getHeader("content-disposition")：获取头信息
		5.文件的真实名称在头信息中,从头信息中进行字符串切割处理,从而获取文件名称（老师给的方法，教材例3-2的方法实际上还是回到老师的方法上）
		6.part.write(path) : 进行文件持久化
 */
@WebServlet(name="resume",/*value= {"/resume2"},*/displayName="这是简历处理Servlet。",//value属性不能与urlPatterns属性同时使用
//,见东软教材《java web开发技术》表3-2
description="这是简历处理系统Servlet。",urlPatterns= {"/resume0","/resume1"},//一个servlet对应两个url映射
initParams={//初始化参数数组，每个元素都是@WebInitParam注解，此处演示商定两个参数，分别是encoding和author
@WebInitParam(name = "encoding", value = "UTF-8"),	
@WebInitParam(name = "author", value = "老王")}
)
@MultipartConfig(
		maxFileSize = 2*1024*1024//限定上传单个文件大小不超过2MB
		
	)
public class resumeupload extends HttpServlet {
	private static final long serialVersionUID = 1L;
	   String username;
       String sex;
       int year;
       String school;
       String resumetext;
       String photo;
       String filename;
       String urlname;
       String uuidfilename;
       String currentTimeString;
       String authorname;
       Part part;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public resumeupload() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//说明输入的请求信息采用UTF-8编码方式
	    response.setHeader("content-type","text/html;charset=UTF-8");//解决使用response.getWriter().write()输出中文乱码问题
		//或者response.setContentType("text/html; charset=UTF-8");
	    request.setCharacterEncoding("UTF-8");//解决Post方式请求中文参数乱码
		PrintWriter out= response.getWriter();
		int nInsert=0;//插入数据库记录成功行数
		String filePath=null;
		try {
			//获取表单内容，如果无异常则连接数据库，将简历写入表中，有异常则处理
			username = request.getParameter("username").trim();
			sex = request.getParameter("sex").trim();
			year = Integer.parseInt(request.getParameter("year").trim());
			school = request.getParameter("school").trim();
			resumetext=request.getParameter("resumetext").trim();
			//获取form表单的Multipart请求的文件的name属性
			part=request.getPart("uploadphoto");//Part类是Servlet3.0提供的，请参看开源中国的JavaEE API文档https://tool.oschina.net/apidocs/apidoc?api=javaEE6
		     //获取文件上传表单原文件名
				/*
				 * 经过过request请求信息的分析， 原文件名在头信息的Content-Disposition中 所以获取Content-Disposition的值举例如下
				 * form-data; name="photo"; filename="测试文件.txt"
				 */
			//获取HTTP头信息header=（form-data; name="file";filename="文件名"）
			String header=part.getHeader("content-disposition");//Tomcat所有版本均可通过取头部的方法再用字符串运算取出文件名
		    filename=getFileName(header);//该方法适用于Tomcat所有版本
		    //从HTTP头信息中获取文件名fileName=（文件名）
//			filename = header.substring(header.lastIndexOf("\\")+1, header.length() - 1);
			System.out.println("resumeupload.java中看一下前端传过来的文件名："+filename);
//			String filename=part.getSubmittedFileName();//直接取文件名，适用于Tomcat8.0及Servlet3.0以上,有时有路径字符串问题！少用！
//		     urlname = URLEncoder.encode(filename, "UTF-8");//如果是中文文件名，编码是必须的 ！因为Get请求地址要用到
		     //获得存储上传文件的文件夹路径，后面和文件名连接形成全路径，数据库字段photo中存放照片文件全路径,当然也可以直接存放照片文件（此处不讲）
		     File savepath=new File(request.getServletContext().getRealPath("/photo"));
		     if (!savepath.exists()) {//如果路径不存在则创建
		            savepath.mkdir();
		        }
		     //保存照片，一定是物理路径， 为防止不同用户上传的照片文件名重名，加上当前日期时间（精确到毫秒）或者加上UUID
//			 SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
//			 currentTimeString=sdf.format(new Date());
//		     filePath = savepath.getPath() + File.separator +currentTimeString + filename;
		     uuidfilename=UUID.randomUUID().toString().replace("-", "")+ filename;
		     System.out.println("resumeupload.java中看一下取的文件名经UUID防重名处理后的含有中文的文件名："+uuidfilename);
		     filePath = savepath.getPath() + File.separator +uuidfilename;
		     //原始的UUID形如 ： 68dcb13d-02ec-4233-b65a-6698830e0b51
		     //替换掉“-”后的UUID形如 ：d39b37b98606404cad9077ae29884330
		     part.write(filePath);// 持久化写入文件（服务器硬盘物理路径）
		     photo=filePath;//为了方便代码可读性将全路径写入数据库相应字段，后面用到此photo
		     System.out.println("resumeupload.java中看一下服务器保存上传照片的全路径："+filePath);
		} catch (NumberFormatException e1) {
			//e1.printStackTrace();
	    	out.write("您输入的简历信息不全，请"+"<a href='jianli.jsp'>返回重新输入</a>"+"<br>");
	    }
		 HttpSession session=request.getSession();
	     out.println("应聘者编号："+session.getAttribute("loginID")+"<br>");
	     out.println("应聘者姓名："+session.getAttribute("loginName")+"<br>");
		//表格展示用户填写的简历
		out.write("<br>");
		out.write("<HTML>");
       out.write("<HEAD><TITLE>简历上传</TITLE></HEAD>");
       out.write("<body bgcolor=\"#BDB2A1\">\n" + "<h1 align=\"center\">" + username+ "个人简历"+"</h1>\n");
       out.write("<table border=1 align=\"center\">\n"); 
       out.write("<tr   bgcolor=\"#FFAD00\">\n"); 
		out.write("<table border=1 class=\"tbb\">\r\n"); 
		out.write("<tr>\r\n"); 
		out.write("<td align=\"center\" width=\"100\">姓名</td>\r\n");
		out.write("<td colspan=\"2\">\r\n" + username+"</td>\r\n"); 
		out.write("<td rowspan=\"2\" align=\"center\">" +"<img src="+photo+"></td>\r\n"); 
		out.write("</tr>\r\n"); 
		out.write("<tr>\r\n" +"<td align=\"center\">性别</td>\r\n" +"<td colspan=\"2\">"+sex+"</td>\r\n");
		out.write("</tr>\r\n");
		out.write("<tr>\r\n" + "<td align=\"center\" width=\"100\">年龄</td>\r\n");
		out.write("<td width=\"60\">"+year+"</td>\r\n");
		out.write("<td align=\"center\" width=\"110\">毕业院校</td>\r\n"); 
		out.write("<td >"+school+"</td>\r\n"); 
		out.write("</tr>\r\n"); 
		out.write("<tr>\r\n" + "<td colspan=\"4\" align=\"center\">主要经历与成绩</td>\r\n" + "</tr>\r\n");
		out.write("<tr>\r\n" + "<td colspan=\"4\" height=\"300\" > \r\n" + resumetext+"</td>\r\n");
		out.write("</tr>\r\n" +"</table>");
		out.write("<br>");
	    //连接数据库保存简历到表中
		Connection con=null;
		java.sql.PreparedStatement pstmt=null;
		try {//把数据库连接工具设计成单独的类更好,减少代码重复！
           //第一步：装载驱动
           Class.forName("com.mysql.cj.jdbc.Driver");
           //第二步：建立连接 
           con = DriverManager.getConnection("jdbc:mysql://localhost:3306/countrystudent?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true","root","123456");
			//第三步：构建并执行预处理sql语句 
           String sqlinsert = "insert into resume values(null,?,?,?,?,?,?)";
           pstmt=con.prepareStatement(sqlinsert);
           pstmt.setString(1, username);
           pstmt.setString(2, sex);
           pstmt.setInt(3,year);
           pstmt.setString(4, school);
           pstmt.setString(5,resumetext);
           pstmt.setString(6,photo);
           nInsert=pstmt.executeUpdate();//执行插入操作
		}catch (Exception ex){ 
			ex.printStackTrace(); 
		}finally {//关闭，必须的！！！！！
			try {
				pstmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			try {
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(nInsert>0) {
		out.write("简历已上传成功！<br/>");
		}
		//out.print("<script language='javascript'>alert('简历填写成功！');window.location.href='jianli.jsp';</script>");
		//getServletContext().getRealPath();获取上下文真实路径,是从当前servlet 在tomcat中的存放文件夹开始计算起的
		//假如项目上下文目录为D:\apache-tomcat-7.0.52\项目名,则：
		//servletContext.getRealPath(""); 返回示例: D:\apache-tomcat-7.0.52\项目名
		//servletContext.getRealPath("/");返回示例: D:\apache-tomcat-7.0.52\项目名\
		//servletContext.getRealPath("/文件名");返回示例: D:\apache-tomcat-7.0.52\项目名\文件名
		//servletContext.getRealPath("/文件夹名/文件名");返回示例: D:\apache-tomcat-7.0.52\项目名\文件夹名\文件名
	     //照片文件保存的路径，保存在当前上下文的photo目录下
   	    // File savepath = new File("D:\\wyjtmp"); //单独指定一个目录存放照片，不建议
	        out.write("<h2>请点击如下链接下载照片试试</h2>");
	        //下载链接中的文件名容易搞错，注意必须是对文件名中文部分，如果全路径进行URL编码，则出错，下载不了！！
	        //这里用了“原始”办法，把上传保存的那刻的时间记录下来或者用UUID，与经过URL编码的文件名合并，形成链接用的文件名。
	        out.write("<a href='photodownload?file=" + URLEncoder.encode(uuidfilename, "UTF-8")+"'>" + uuidfilename + "</a>");//跳转到下载照片的servlet程序：photodownload.java
	        out.println("<br><h3><a href='LogoutServlet'>注销离开</a></h3>");
	        /*也可以用转发方式跳转，如
	         *request.setAttribute("message", "文件上传成功!");//加上请求信息再跳
       	  request.getRequestDispatcher("lookup").forward(request, response);
	         */
	        out.println("本项目作者"+authorname);
	        out.println("</BODY>");
	        out.println("</HTML>");
	        out.flush();
	        out.close();
	}
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
	@Override
	public void init(ServletConfig config) throws ServletException {//获取初始化信息：张三  
	authorname = config.getInitParameter("author");
	}
	public String getFileName(String header) {//该方法适用于Tomcat7.0，Tomcat8.0以上直接用part.getSubmittedFileName()获取文件名
       /**关于Part对象及其Header结构信息及本方法代码来由见博客：
        * https://blog.csdn.net/qq_41741576/article/details/97624120
        * https://blog.csdn.net/qq_40618558/article/details/80052199
        * 因为传过来的是头部信息格式形如：form-data; name="file"; filename="xxxxx.xxx"
        * String[] tempArr1 = header.split(";");代码执行完之后，在不同的浏览器下，tempArr1数组里面的内容稍有区别
        * 火狐或者google浏览器下：tempArr1={form-data,name="file",filename="snmp4j--api.zip"}
        * IE浏览器下：tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"}
        */
       String[] tempArr1 = header.split(";");
       /**
        * 火狐或者google浏览器下：tempArr2={filename,"snmp4j--api.zip"}
        * IE浏览器下：tempArr2={filename,"E:\snmp4j--api.zip"}
        */
       String[] tempArr2 = tempArr1[2].split("=");
       // 获取文件名，兼容各种浏览器的写法
       String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", "");
       return fileName;

}
}